package com.dream.network.utils;

import android.util.Log;

import com.dream.network.HttpRequest;
import com.dream.network.HttpResponse;
import com.dream.network.HttpTask;

import java.io.IOException;
import java.security.cert.CertificateException;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;

/**
 * Description: TODO
 * author: Wang
 * date: 3/9/17 16:59
 * email:life_artist@163.com
 * Copyright©2017 by wang. All rights reserved.
 */
public class HttpSSLClient {

    public static final int TIME_OUT = 15 * 1000;
    private static String sUserAgent;
    private static HttpSSLClient sInstance;
    private OkHttpClient mClient;

    public HttpSSLClient() {
        mClient = newClient();
    }

    public static HttpSSLClient getInstance() {
        if (sInstance == null) {
            synchronized (HttpClient.class) {
                if (sInstance == null) {
                    sInstance = new HttpSSLClient();
                }
            }
        }
        return sInstance;
    }

    public static HttpTask addRequest(HttpRequest request) {
        if (request == null) {
            return null;
        }
        Request requestInfo = getRequest(request);
        Call call = getInstance().getClient().newCall(requestInfo);
        HttpTask task = new HttpTask();
        task.setRequest(request);
        task.enqueue(call);
        return task;
    }

    public static HttpResponse addRequestSync(HttpRequest request) {
        if (request == null) {
            return null;
        }

        Call call = getInstance().getClient().newCall(getRequest(request));
        try {
            return new HttpResponse(call.execute());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public OkHttpClient getClient() {
        return mClient;
    }

    public static OkHttpClient newClient() {

        try {
            // Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                @Override
                public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                }

                @Override
                public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                }

                @Override
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return new java.security.cert.X509Certificate[]{};
                }
            }};

            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts,
                    new java.security.SecureRandom());
            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext
                    .getSocketFactory();


            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.connectTimeout(TIME_OUT, TimeUnit.MILLISECONDS);
            builder.readTimeout(TIME_OUT, TimeUnit.MILLISECONDS);
            builder.writeTimeout(TIME_OUT, TimeUnit.MILLISECONDS);
            builder.retryOnConnectionFailure(false);
            builder.sslSocketFactory(sslSocketFactory);
            builder.hostnameVerifier(new HostnameVerifier() {

                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;

                }
            });

            return builder.build();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    private static Request getRequest(HttpRequest request) {
        if (request == null)
            return null;

        Request.Builder builder = new Request.Builder();
        String url = request.getUrl();
        if (HttpRequest.HttpMethod.GET == request.mMethod) {
            url += request.getParameterForGet();
            Log.i("Http  :  ", url);
        }
        //LOG
//        LiveLog.d("http", "url = "+url);
        builder.url(url);
        builder.tag(request.getTag());
        builder.headers(request.getRequestHeaders());
        switch (request.mMethod) {
            case HttpRequest.HttpMethod.GET:
                builder.get();
                break;
            case HttpRequest.HttpMethod.POST:
                if (request.isFilePost() || request.isStreamPost()) {
                    builder.post(request.getRequestBodyFile());
                } else {
                    builder.post(request.getRequestBody());
                }
                break;
            default:
                throw new RuntimeException("Unsupported http method.");
        }
        return builder.build();
    }

    /**
     * 加载证书
     */
//    private static X509Certificate loadCertificate(int id) {
//        InputStream in = null;
//        try {
//            CertificateFactory cf = CertificateFactory.getInstance("X.509");
//            in = BaseApplication.getContext().getResources().openRawResource(id);
//            X509Certificate cert = (X509Certificate) cf.generateCertificate(in);
//            return cert;
//        } catch (Exception e) {
//            e.printStackTrace();
//            return null;
//        } finally {
//            if (in != null) {
//                try {
//                    in.close();
//                } catch (IOException e) {
//                }
//            }
//        }
//    }
}
